//--------------------------------------------------------------------------
// 
//  Copyright (c) Chili Software.  All rights reserved. 
// 
//  File: IPersistentQueriesProvider.cs
//
//  Description: Implemented to create custom query statements for a 
//               persistent object.
// 
//--------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Text;
using Chili.Opf3.Query;
using Chili.Opf3.Storages;

namespace Chili.Opf3
{
	/// <summary>
	/// An interface that is implemented to create custom queries for a persistent object's insert,
	/// update and delete operations.
	/// </summary>
	/// <remarks>
	/// <para>
	/// This interface is implemented to create custom queries for a persistent's insert, update and 
	/// delete operations. The interface contains a method for each operation: The class may return an own query 
	/// or return the query that is created by the framework. It's not required that a custom query is created for
	/// each operation.
	/// </para>
	/// <para>
	/// It's also required to specify the persistent's type that this class is created for! Each class can only be used for
	/// one given persistent object type.
	/// </para>
	/// </remarks>
	/// <example>This example shows how to implement the IPersistentQueriesProvider interface and how to register
	/// it with the <see cref="ObjectContext">ObjectContext</see>.
	/// <code lang="CS">
	/// public sealed class CallQueriesProvider : IPersistentQueriesProvider
	/// {
	///     public IQuery GetInsertQuery(IStorage storage, object persistent)
	///     {
	///         // Return the null to have the framework create the query.
	///         return null;
	///     }
	/// 
	///     public IQuery GetUpdateQuery(IStorage storage, IQuery query, object persistent)
	///     {
	///         Call c = (Call)persistent;
	///         // Check if the storage is the MsSqlStorage.
	///         if (storage is MsSqlStorage)
	///         {
	///             // If that's true, create a custom query and return that query.
	///             return new SqlQuery("UPDATE CALLS SET DURATION = {0} WHERE ID = {1}", c.Duration, c.ID);
	///         }
	///         // Otherwise return null.
	///         return null;
	///     }
	/// 
	///     public IQuery GetDeleteQuery(IStorage storage, IQuery query, object persistent)
	///     {
	///         // Return the null to have the framework create the query.
	///         return null;
	///     }
	/// 
	///     // Return the type of persistent this class has been created for.
	///     public Type PersistentType
	///     {
	///         get { return typeof(Call); }
	///     }
	/// }
	/// 
	/// // ... Other code.
	/// 
	/// // Register the provider with the ObjectContext instance.
	/// context.PersistentQueriesProviders.Add(new CallQueriesProvider());
	/// </code>
	/// </example>
	public interface IPersistentQueriesProvider
	{
		/// <summary>
		/// Creates and returns a query for the persistent's insert operation; or null if the query generated by the framework should be used.
		/// </summary>
		/// <param name="storage">The storage the query is created for. By checking the storage type different optimized queries may be created.</param>
		/// <param name="persistent">The persistent object that's going to be inserted.</param>
		/// <returns>An class that implements the <see cref="IQuery">IQuery</see> interface; or null if the query generated by the framework should be used.</returns>
		IQuery GetInsertQuery(IStorage storage, object persistent);

		/// <summary>
		/// Creates and returns a query for the persistent's update operation; or null if the query generated by the framework should be used.
		/// </summary>
		/// <param name="storage">The storage the query is created for. By checking the storage type different optimized queries may be created.</param>
		/// <param name="persistent">The persistent object that's going to be updated.</param>
		/// <returns>An class that implements the <see cref="IQuery">IQuery</see> interface; or null if the query generated by the framework should be used.</returns>
		IQuery GetUpdateQuery(IStorage storage, object persistent);

		/// <summary>
		/// Creates and returns a query for the persistent's delete operation; or null if the query generated by the framework should be used.
		/// </summary>
		/// <param name="storage">The storage the query is created for. By checking the storage type different optimized queries may be created.</param>
		/// <param name="persistent">The persistent object that's going to be deleted.</param>
		/// <returns>An class that implements the <see cref="IQuery">IQuery</see> interface; or null if the query generated by the framework should be used.</returns>
		IQuery GetDeleteQuery(IStorage storage, object persistent);

		/// <summary>
		/// Gets the type of the persistent object.
		/// </summary>
		Type PersistentType
		{
			get;
		}
	}
}
